package com.example.analyzevisio.utis;

import com.example.analyzevisio.model.*;
import com.example.analyzevisio.model.node.failnode.FailNode;
import com.example.analyzevisio.model.node.startnode.StartNode;
import com.example.analyzevisio.model.node.succeednode.SucceedNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.util.*;

import static com.example.analyzevisio.service.ConnectService.getConnect;
import static com.example.analyzevisio.service.JudgeService.getJudge;
import static com.example.analyzevisio.service.LaneService.getLane;
import static com.example.analyzevisio.service.NodeService.*;
import static com.example.analyzevisio.service.ServiceNodeService.getServiceNode;
import static com.example.analyzevisio.utis.Obtain.*;

public class VSDXParser {

    private static HashMap<String, String> typeMap;


    public void setTypeMap(HashMap<String, String> typeMap) {
        this.typeMap = typeMap;
    }

    public static String parsePageXml(String pageFilePath, String FilePath) throws Exception {

        int start = 0, fail = 0, success = 0;

        List<Object> shapes = new ArrayList<>();

        File xmlFile = new File(pageFilePath);
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(xmlFile);
        doc.getDocumentElement().normalize();

        NodeList shapeNodes = doc.getElementsByTagName("Shape");
        NodeList shapeConnect = doc.getElementsByTagName("Connect");

        extracted(FilePath, shapeNodes);

        for (int i = 0; i < shapeNodes.getLength(); i++) {
            Element shapeElement = (Element) shapeNodes.item(i);

            String shapeMaster = shapeElement.getAttribute("Master");
            NodeList textNodes = shapeElement.getElementsByTagName("Text");
            String text = getText(textNodes);

            if (typeMap.containsKey("泳道") && typeMap.get("泳道").equals(shapeMaster)) {

                //泳道
                Lane lane = getLane(shapeElement, textNodes);
                shapes.add(lane);
            } else if (typeMap.containsKey("动态连接线") && typeMap.get("动态连接线").equals(shapeMaster)) {
                //连接线
                Connect connect = getConnect(shapeElement, shapeConnect, text);
                shapes.add(connect);
            } else if (typeMap.containsKey("开始/结束") && typeMap.get("开始/结束").equals(shapeMaster)) {
                //节点

                if ("失败".equals(text)) {
                    fail++;
                    FailNode failNode = getFailNode(shapeElement, text);
                    shapes.add(failNode);
                } else if ("开始".equals(text)) {
                    start++;
                    StartNode startNode = getStartNode(shapeElement);
                    shapes.add(startNode);
                } else if ("成功".equals(text)) {
                    success++;
                    SucceedNode succeedNode = getSucceedNode(shapeElement, text);
                    shapes.add(succeedNode);
                } else {
                    throw new RuntimeException("\"" + text + "\"" + "该节点未被识别为起始节点，请注意查看");
                }


            } else if (typeMap.containsKey("判定") && typeMap.get("判定").equals(shapeMaster)) {
                //判断节点
                Judge judge = getJudge(shapeElement, textNodes);
                shapes.add(judge);
            } else if (typeMap.containsKey("流程") && typeMap.get("流程").equals(shapeMaster)) {
                //服务节点
                ServiceNode serviceNode = getServiceNode(shapeElement, text);
                shapes.add(serviceNode);
            }

        }
        //判断节点是否正常
        nodeJudgment(start, fail, success);

        //判断是否存在未被连接的节点
        HashMap<String, Map<String, String>> dataMap = getDataMap();
        for (String s : dataMap.keySet()) {
            String type = dataMap.get(s).get("type");

            if ("流程".equals(type) ||
                "失败".equals(type) ||
                "成功".equals(type) ||
                "开始".equals(type) ||
                "判断".equals(type)
            ){
                if (Integer.parseInt(dataMap.get(s).get("sum")) == 0){
                    throw new RuntimeException( type + "节点未被连接线连接，请注意");
                }
                String enterJudgment = dataMap.get(s).get("enterJudgment");
                if (!("开始".equals(type))){
                    if ("false".equals(enterJudgment)){
                        throw new RuntimeException( type + "节点没有连入，请注意");
                    }
                }
            }
        }


        // 将泳道信息序列化为JSON
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(shapes);

        return json;
    }
}
